home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / wave.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  19KB  |  569 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. """Stuff to parse WAVE files.
  5.  
  6. Usage.
  7.  
  8. Reading WAVE files:
  9.       f = wave.open(file, 'r')
  10. where file is either the name of a file or an open file pointer.
  11. The open file pointer must have methods read(), seek(), and close().
  12. When the setpos() and rewind() methods are not used, the seek()
  13. method is not  necessary.
  14.  
  15. This returns an instance of a class with the following public methods:
  16.       getnchannels()  -- returns number of audio channels (1 for
  17.                          mono, 2 for stereo)
  18.       getsampwidth()  -- returns sample width in bytes
  19.       getframerate()  -- returns sampling frequency
  20.       getnframes()    -- returns number of audio frames
  21.       getcomptype()   -- returns compression type ('NONE' for linear samples)
  22.       getcompname()   -- returns human-readable version of
  23.                          compression type ('not compressed' linear samples)
  24.       getparams()     -- returns a tuple consisting of all of the
  25.                          above in the above order
  26.       getmarkers()    -- returns None (for compatibility with the
  27.                          aifc module)
  28.       getmark(id)     -- raises an error since the mark does not
  29.                          exist (for compatibility with the aifc module)
  30.       readframes(n)   -- returns at most n frames of audio
  31.       rewind()        -- rewind to the beginning of the audio stream
  32.       setpos(pos)     -- seek to the specified position
  33.       tell()          -- return the current position
  34.       close()         -- close the instance (make it unusable)
  35. The position returned by tell() and the position given to setpos()
  36. are compatible and have nothing to do with the actual position in the
  37. file.
  38. The close() method is called automatically when the class instance
  39. is destroyed.
  40.  
  41. Writing WAVE files:
  42.       f = wave.open(file, 'w')
  43. where file is either the name of a file or an open file pointer.
  44. The open file pointer must have methods write(), tell(), seek(), and
  45. close().
  46.  
  47. This returns an instance of a class with the following public methods:
  48.       setnchannels(n) -- set the number of channels
  49.       setsampwidth(n) -- set the sample width
  50.       setframerate(n) -- set the frame rate
  51.       setnframes(n)   -- set the number of frames
  52.       setcomptype(type, name)
  53.                       -- set the compression type and the
  54.                          human-readable compression type
  55.       setparams(tuple)
  56.                       -- set all parameters at once
  57.       tell()          -- return current position in output file
  58.       writeframesraw(data)
  59.                       -- write audio frames without pathing up the
  60.                          file header
  61.       writeframes(data)
  62.                       -- write audio frames and patch up the file header
  63.       close()         -- patch up the file header and close the
  64.                          output file
  65. You should set the parameters before the first writeframesraw or
  66. writeframes.  The total number of frames does not need to be set,
  67. but when it is set to the correct value, the header does not have to
  68. be patched up.
  69. It is best to first set all parameters, perhaps possibly the
  70. compression type, and then write audio frames using writeframesraw.
  71. When all frames have been written, either call writeframes('') or
  72. close() to patch up the sizes in the header.
  73. The close() method is called automatically when the class instance
  74. is destroyed.
  75. """
  76. import __builtin__
  77. __all__ = [
  78.     'open',
  79.     'openfp',
  80.     'Error']
  81.  
  82. class Error(Exception):
  83.     pass
  84.  
  85. WAVE_FORMAT_PCM = 1
  86. _array_fmts = (None, 'b', 'h', None, 'l')
  87. import struct
  88. if struct.pack('h', 1) == '\x00\x01':
  89.     big_endian = 1
  90. else:
  91.     big_endian = 0
  92. from chunk import Chunk
  93.  
  94. class Wave_read:
  95.     """Variables used in this class:
  96.  
  97.     These variables are available to the user though appropriate
  98.     methods of this class:
  99.     _file -- the open file with methods read(), close(), and seek()
  100.               set through the __init__() method
  101.     _nchannels -- the number of audio channels
  102.               available through the getnchannels() method
  103.     _nframes -- the number of audio frames
  104.               available through the getnframes() method
  105.     _sampwidth -- the number of bytes per audio sample
  106.               available through the getsampwidth() method
  107.     _framerate -- the sampling frequency
  108.               available through the getframerate() method
  109.     _comptype -- the AIFF-C compression type ('NONE' if AIFF)
  110.               available through the getcomptype() method
  111.     _compname -- the human-readable AIFF-C compression type
  112.               available through the getcomptype() method
  113.     _soundpos -- the position in the audio stream
  114.               available through the tell() method, set through the
  115.               setpos() method
  116.  
  117.     These variables are used internally only:
  118.     _fmt_chunk_read -- 1 iff the FMT chunk has been read
  119.     _data_seek_needed -- 1 iff positioned correctly in audio
  120.               file for readframes()
  121.     _data_chunk -- instantiation of a chunk class for the DATA chunk
  122.     _framesize -- size of one frame in the file
  123.     """
  124.     
  125.     def initfp(self, file):
  126.         self._convert = None
  127.         self._soundpos = 0
  128.         self._file = Chunk(file, bigendian = 0)
  129.         if self._file.getname() != 'RIFF':
  130.             raise Error, 'file does not start with RIFF id'
  131.         
  132.         if self._file.read(4) != 'WAVE':
  133.             raise Error, 'not a WAVE file'
  134.         
  135.         self._fmt_chunk_read = 0
  136.         self._data_chunk = None
  137.         while None:
  138.             self._data_seek_needed = 1
  139.             
  140.             try:
  141.                 chunk = Chunk(self._file, bigendian = 0)
  142.             except EOFError:
  143.                 break
  144.  
  145.             chunkname = chunk.getname()
  146.             if chunkname == 'fmt ':
  147.                 self._read_fmt_chunk(chunk)
  148.                 self._fmt_chunk_read = 1
  149.             elif chunkname == 'data':
  150.                 if not self._fmt_chunk_read:
  151.                     raise Error, 'data chunk before fmt chunk'
  152.                 
  153.                 self._data_chunk = chunk
  154.                 self._nframes = chunk.chunksize // self._framesize
  155.                 self._data_seek_needed = 0
  156.                 break
  157.             
  158.             continue
  159.             if not (self._fmt_chunk_read) or not (self._data_chunk):
  160.                 raise Error, 'fmt chunk and/or data chunk missing'
  161.             
  162.  
  163.     
  164.     def __init__(self, f):
  165.         self._i_opened_the_file = None
  166.         if isinstance(f, basestring):
  167.             f = __builtin__.open(f, 'rb')
  168.             self._i_opened_the_file = f
  169.         
  170.         
  171.         try:
  172.             self.initfp(f)
  173.         except:
  174.             if self._i_opened_the_file:
  175.                 f.close()
  176.             
  177.             raise 
  178.  
  179.  
  180.     
  181.     def __del__(self):
  182.         self.close()
  183.  
  184.     
  185.     def getfp(self):
  186.         return self._file
  187.  
  188.     
  189.     def rewind(self):
  190.         self._data_seek_needed = 1
  191.         self._soundpos = 0
  192.  
  193.     
  194.     def close(self):
  195.         if self._i_opened_the_file:
  196.             self._i_opened_the_file.close()
  197.             self._i_opened_the_file = None
  198.         
  199.         self._file = None
  200.  
  201.     
  202.     def tell(self):
  203.         return self._soundpos
  204.  
  205.     
  206.     def getnchannels(self):
  207.         return self._nchannels
  208.  
  209.     
  210.     def getnframes(self):
  211.         return self._nframes
  212.  
  213.     
  214.     def getsampwidth(self):
  215.         return self._sampwidth
  216.  
  217.     
  218.     def getframerate(self):
  219.         return self._framerate
  220.  
  221.     
  222.     def getcomptype(self):
  223.         return self._comptype
  224.  
  225.     
  226.     def getcompname(self):
  227.         return self._compname
  228.  
  229.     
  230.     def getparams(self):
  231.         return (self.getnchannels(), self.getsampwidth(), self.getframerate(), self.getnframes(), self.getcomptype(), self.getcompname())
  232.  
  233.     
  234.     def getmarkers(self):
  235.         pass
  236.  
  237.     
  238.     def getmark(self, id):
  239.         raise Error, 'no marks'
  240.  
  241.     
  242.     def setpos(self, pos):
  243.         if pos < 0 or pos > self._nframes:
  244.             raise Error, 'position not in range'
  245.         
  246.         self._soundpos = pos
  247.         self._data_seek_needed = 1
  248.  
  249.     
  250.     def readframes(self, nframes):
  251.         if self._data_seek_needed:
  252.             self._data_chunk.seek(0, 0)
  253.             pos = self._soundpos * self._framesize
  254.             if pos:
  255.                 self._data_chunk.seek(pos, 0)
  256.             
  257.             self._data_seek_needed = 0
  258.         
  259.         if nframes == 0:
  260.             return ''
  261.         
  262.         if self._sampwidth > 1 and big_endian:
  263.             import array as array
  264.             chunk = self._data_chunk
  265.             data = array.array(_array_fmts[self._sampwidth])
  266.             nitems = nframes * self._nchannels
  267.             if nitems * self._sampwidth > chunk.chunksize - chunk.size_read:
  268.                 nitems = (chunk.chunksize - chunk.size_read) / self._sampwidth
  269.             
  270.             data.fromfile(chunk.file.file, nitems)
  271.             chunk.size_read = chunk.size_read + nitems * self._sampwidth
  272.             chunk = chunk.file
  273.             chunk.size_read = chunk.size_read + nitems * self._sampwidth
  274.             data.byteswap()
  275.             data = data.tostring()
  276.         else:
  277.             data = self._data_chunk.read(nframes * self._framesize)
  278.         if self._convert and data:
  279.             data = self._convert(data)
  280.         
  281.         self._soundpos = self._soundpos + len(data) // self._nchannels * self._sampwidth
  282.         return data
  283.  
  284.     
  285.     def _read_fmt_chunk(self, chunk):
  286.         (wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign) = struct.unpack('<hhllh', chunk.read(14))
  287.         if wFormatTag == WAVE_FORMAT_PCM:
  288.             sampwidth = struct.unpack('<h', chunk.read(2))[0]
  289.             self._sampwidth = (sampwidth + 7) // 8
  290.         else:
  291.             raise Error, 'unknown format: %r' % (wFormatTag,)
  292.         self._framesize = self._nchannels * self._sampwidth
  293.         self._comptype = 'NONE'
  294.         self._compname = 'not compressed'
  295.  
  296.  
  297.  
  298. class Wave_write:
  299.     """Variables used in this class:
  300.  
  301.     These variables are user settable through appropriate methods
  302.     of this class:
  303.     _file -- the open file with methods write(), close(), tell(), seek()
  304.               set through the __init__() method
  305.     _comptype -- the AIFF-C compression type ('NONE' in AIFF)
  306.               set through the setcomptype() or setparams() method
  307.     _compname -- the human-readable AIFF-C compression type
  308.               set through the setcomptype() or setparams() method
  309.     _nchannels -- the number of audio channels
  310.               set through the setnchannels() or setparams() method
  311.     _sampwidth -- the number of bytes per audio sample
  312.               set through the setsampwidth() or setparams() method
  313.     _framerate -- the sampling frequency
  314.               set through the setframerate() or setparams() method
  315.     _nframes -- the number of audio frames written to the header
  316.               set through the setnframes() or setparams() method
  317.  
  318.     These variables are used internally only:
  319.     _datalength -- the size of the audio samples written to the header
  320.     _nframeswritten -- the number of frames actually written
  321.     _datawritten -- the size of the audio samples actually written
  322.     """
  323.     
  324.     def __init__(self, f):
  325.         self._i_opened_the_file = None
  326.         if isinstance(f, basestring):
  327.             f = __builtin__.open(f, 'wb')
  328.             self._i_opened_the_file = f
  329.         
  330.         
  331.         try:
  332.             self.initfp(f)
  333.         except:
  334.             if self._i_opened_the_file:
  335.                 f.close()
  336.             
  337.             raise 
  338.  
  339.  
  340.     
  341.     def initfp(self, file):
  342.         self._file = file
  343.         self._convert = None
  344.         self._nchannels = 0
  345.         self._sampwidth = 0
  346.         self._framerate = 0
  347.         self._nframes = 0
  348.         self._nframeswritten = 0
  349.         self._datawritten = 0
  350.         self._datalength = 0
  351.  
  352.     
  353.     def __del__(self):
  354.         self.close()
  355.  
  356.     
  357.     def setnchannels(self, nchannels):
  358.         if self._datawritten:
  359.             raise Error, 'cannot change parameters after starting to write'
  360.         
  361.         if nchannels < 1:
  362.             raise Error, 'bad # of channels'
  363.         
  364.         self._nchannels = nchannels
  365.  
  366.     
  367.     def getnchannels(self):
  368.         if not self._nchannels:
  369.             raise Error, 'number of channels not set'
  370.         
  371.         return self._nchannels
  372.  
  373.     
  374.     def setsampwidth(self, sampwidth):
  375.         if self._datawritten:
  376.             raise Error, 'cannot change parameters after starting to write'
  377.         
  378.         if sampwidth < 1 or sampwidth > 4:
  379.             raise Error, 'bad sample width'
  380.         
  381.         self._sampwidth = sampwidth
  382.  
  383.     
  384.     def getsampwidth(self):
  385.         if not self._sampwidth:
  386.             raise Error, 'sample width not set'
  387.         
  388.         return self._sampwidth
  389.  
  390.     
  391.     def setframerate(self, framerate):
  392.         if self._datawritten:
  393.             raise Error, 'cannot change parameters after starting to write'
  394.         
  395.         if framerate <= 0:
  396.             raise Error, 'bad frame rate'
  397.         
  398.         self._framerate = framerate
  399.  
  400.     
  401.     def getframerate(self):
  402.         if not self._framerate:
  403.             raise Error, 'frame rate not set'
  404.         
  405.         return self._framerate
  406.  
  407.     
  408.     def setnframes(self, nframes):
  409.         if self._datawritten:
  410.             raise Error, 'cannot change parameters after starting to write'
  411.         
  412.         self._nframes = nframes
  413.  
  414.     
  415.     def getnframes(self):
  416.         return self._nframeswritten
  417.  
  418.     
  419.     def setcomptype(self, comptype, compname):
  420.         if self._datawritten:
  421.             raise Error, 'cannot change parameters after starting to write'
  422.         
  423.         if comptype not in ('NONE',):
  424.             raise Error, 'unsupported compression type'
  425.         
  426.         self._comptype = comptype
  427.         self._compname = compname
  428.  
  429.     
  430.     def getcomptype(self):
  431.         return self._comptype
  432.  
  433.     
  434.     def getcompname(self):
  435.         return self._compname
  436.  
  437.     
  438.     def setparams(self, .1):
  439.         (nchannels, sampwidth, framerate, nframes, comptype, compname) = .1
  440.         if self._datawritten:
  441.             raise Error, 'cannot change parameters after starting to write'
  442.         
  443.         self.setnchannels(nchannels)
  444.         self.setsampwidth(sampwidth)
  445.         self.setframerate(framerate)
  446.         self.setnframes(nframes)
  447.         self.setcomptype(comptype, compname)
  448.  
  449.     
  450.     def getparams(self):
  451.         if not (self._nchannels) and not (self._sampwidth) or not (self._framerate):
  452.             raise Error, 'not all parameters set'
  453.         
  454.         return (self._nchannels, self._sampwidth, self._framerate, self._nframes, self._comptype, self._compname)
  455.  
  456.     
  457.     def setmark(self, id, pos, name):
  458.         raise Error, 'setmark() not supported'
  459.  
  460.     
  461.     def getmark(self, id):
  462.         raise Error, 'no marks'
  463.  
  464.     
  465.     def getmarkers(self):
  466.         pass
  467.  
  468.     
  469.     def tell(self):
  470.         return self._nframeswritten
  471.  
  472.     
  473.     def writeframesraw(self, data):
  474.         self._ensure_header_written(len(data))
  475.         nframes = len(data) // self._sampwidth * self._nchannels
  476.         if self._convert:
  477.             data = self._convert(data)
  478.         
  479.         if self._sampwidth > 1 and big_endian:
  480.             import array
  481.             data = array.array(_array_fmts[self._sampwidth], data)
  482.             data.byteswap()
  483.             data.tofile(self._file)
  484.             self._datawritten = self._datawritten + len(data) * self._sampwidth
  485.         else:
  486.             self._file.write(data)
  487.             self._datawritten = self._datawritten + len(data)
  488.         self._nframeswritten = self._nframeswritten + nframes
  489.  
  490.     
  491.     def writeframes(self, data):
  492.         self.writeframesraw(data)
  493.         if self._datalength != self._datawritten:
  494.             self._patchheader()
  495.         
  496.  
  497.     
  498.     def close(self):
  499.         if self._file:
  500.             self._ensure_header_written(0)
  501.             if self._datalength != self._datawritten:
  502.                 self._patchheader()
  503.             
  504.             self._file.flush()
  505.             self._file = None
  506.         
  507.         if self._i_opened_the_file:
  508.             self._i_opened_the_file.close()
  509.             self._i_opened_the_file = None
  510.         
  511.  
  512.     
  513.     def _ensure_header_written(self, datasize):
  514.         if not self._datawritten:
  515.             if not self._nchannels:
  516.                 raise Error, '# channels not specified'
  517.             
  518.             if not self._sampwidth:
  519.                 raise Error, 'sample width not specified'
  520.             
  521.             if not self._framerate:
  522.                 raise Error, 'sampling rate not specified'
  523.             
  524.             self._write_header(datasize)
  525.         
  526.  
  527.     
  528.     def _write_header(self, initlength):
  529.         self._file.write('RIFF')
  530.         if not self._nframes:
  531.             self._nframes = initlength / self._nchannels * self._sampwidth
  532.         
  533.         self._datalength = self._nframes * self._nchannels * self._sampwidth
  534.         self._form_length_pos = self._file.tell()
  535.         self._file.write(struct.pack('<l4s4slhhllhh4s', 36 + self._datalength, 'WAVE', 'fmt ', 16, WAVE_FORMAT_PCM, self._nchannels, self._framerate, self._nchannels * self._framerate * self._sampwidth, self._nchannels * self._sampwidth, self._sampwidth * 8, 'data'))
  536.         self._data_length_pos = self._file.tell()
  537.         self._file.write(struct.pack('<l', self._datalength))
  538.  
  539.     
  540.     def _patchheader(self):
  541.         if self._datawritten == self._datalength:
  542.             return None
  543.         
  544.         curpos = self._file.tell()
  545.         self._file.seek(self._form_length_pos, 0)
  546.         self._file.write(struct.pack('<l', 36 + self._datawritten))
  547.         self._file.seek(self._data_length_pos, 0)
  548.         self._file.write(struct.pack('<l', self._datawritten))
  549.         self._file.seek(curpos, 0)
  550.         self._datalength = self._datawritten
  551.  
  552.  
  553.  
  554. def open(f, mode = None):
  555.     if mode is None:
  556.         if hasattr(f, 'mode'):
  557.             mode = f.mode
  558.         else:
  559.             mode = 'rb'
  560.     
  561.     if mode in ('r', 'rb'):
  562.         return Wave_read(f)
  563.     elif mode in ('w', 'wb'):
  564.         return Wave_write(f)
  565.     else:
  566.         raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"
  567.  
  568. openfp = open
  569.